package com.autonavi.yunda.yunji.core.utils

import com.autonavi.yunda.yunji.common.exception.AmapException
import com.autonavi.yunda.yunji.common.exception.AmapExceptionCode

import java.util.stream.Collectors

@SuppressWarnings(['unused'])
class DynamicSqlUtil {

    static Object notNull(Object obj, Object statement) {
        if (obj == null) {
            return null
        }
        return statement
    }

    static Object NN(Object obj, Object statement) {
        return notEmpty(obj, statement)
    }

    static Object N(Object obj, Object statement) {
        if (obj) return statement
        return null
    }

    static Object WHERE(Object elements) {
        if (elements == null || !elements instanceof ArrayList) {
            return ""
        }
        def elms = elements as ArrayList
        if (elms.findAll().size() == 0) {
            return ""
        }
        elms.findAll().stream().collect(Collectors.joining(" AND ", " WHERE ", ""))
    }

    static SELECT = { String table, Object elements, Object whereElements ->
        if (whereElements != null) {
            """select ${elements.findAll().join(",")} from $table """ + WHERE(whereElements)
        } else {
            """select ${elements.findAll().join(",")} from $table """
        }
    }

    static Object IN(Object elements) {
        if (elements == null || !elements instanceof ArrayList) {
            return ""
        }
        def elms = elements as ArrayList
        return elms.findAll().collect { it.toString().replaceAll("'", "''") }.stream().collect(Collectors.joining("','", " IN ('", "') "))
    }

    /**
     * in 语句优化
     * @param key 列名称
     * @param elements 列表
     * @return
     */
    static Object IN(String key, def elements, boolean trueWhenEmpty = false, String delimiter = ",") {
        if (elements == null
                || (elements instanceof String && elements == '')
                || ((elements instanceof ArrayList || elements instanceof Object[]) && elements.size() == 0)) {
            return trueWhenEmpty ? " 1 = 1 " : " 1 != 1 "
        }
        if (elements instanceof String) {
            return elements.split(delimiter)
                    .collect { it.toString().replaceAll("'", "''") }.stream().collect(Collectors.joining("','", " $key IN ('", "') "))
        } else if (elements instanceof List || elements instanceof Object[]) {
            return elements.findAll().collect { it.toString().replaceAll("'", "''") }.stream().collect(Collectors.joining("','", " $key IN ('", "') "))
        } else {
            throw new AmapException(AmapExceptionCode.COMMON_ILLEGAL_PARAM, "elements must be String or Array")
        }
    }

    static Object INSERT(String table, Object elements, Closure ignore) {
        return doInsertORUpdate(table, elements, ignore, "insert")
    }

    static Object INSERT(String table, Object elements, String ignore) {
        if ("NULL" == ignore || "null" == ignore) {
            INSERT(table, elements, { it == null })
        } else {
            INSERT(table, elements, { !it })
        }
    }

    /**
     *
     * @param table
     * @param cols insertCols  当col为List时[数据库字段名,value数据源key映射,默认值]
     * @param values
     * @return
     */
    static Object INSERT(String table, List cols, List<Map> values) {
        """INSERT INTO $table (${cols.collect { col -> col instanceof List ? col[0] : col }.join(',')}) VALUES ${
            values.collect { vm ->
                "(" + cols.collect {
                    def key = it instanceof List ? (it.size() > 1 && it[1] != null ? it[1] : it[0]) : it;
                    if (vm.get(key) == null) {
                        //default值
                        if (it instanceof List && it.size() > 2) {
                            return "'${it[2]}'"
                        }
                        return "NULL"
                    } else {
                        def value = vm.get(key)
                        if (value instanceof String) {
                            value = value.replaceAll("'", "''")
                        }
                        return "'${value}'"
                    }
                }.join(",") + ")"
            }.join(",")
        }"""
    }

    static Object INSERT(String table, Object elements) {
        return INSERT(table, elements, "empty")
    }

    static Object UPDATE(String table, Object elements, Object whereElement) {
        return UPDATE(table, elements, "empty") + WHERE(whereElement)
    }

    static Object UPDATE(String table, Object elements, String ignore) {
        if ("NULL" == ignore || "null" == ignore) {
            doInsertORUpdate(table, elements, { it == null }, "update")
        } else {
            doInsertORUpdate(table, elements, { !it }, "update")
        }
    }

    static Object UPDATE(String table, Object elements, Closure ignore) {
        doInsertORUpdate(table, elements, ignore, "update")
    }

    static Object doInsertORUpdate(String table, Object elements, Closure ignore, String op) {
        if (elements == null || !elements instanceof Map) {
            return null
        }
        def elms = elements as Map
        if (elms.size() == 0) {
            return null
        }
        def noIgnore = elms.findAll { !ignore.call(it.value) }
        if (noIgnore.size() == 0) {
            return null
        }
        if (op == "insert") {
            return """INSERT INTO $table(${noIgnore.collect { it.key }.join(",")}) values (${noIgnore.collect {
                String value = it.value.toString()
                String replacedValue = value.replaceAll("'", "''")
                value.startsWith("'") ? value : "'$replacedValue'"
            }.join(",")})"""
        } else {
            return """UPDATE $table SET ${noIgnore.collect { it.value.toString().startsWith("'") ? " $it.key = $it.value" : " $it.key = '$it.value'" }.join(",")}"""
        }
    }

    static Object notEmpty(Object obj, Object statement) {
        if (obj == null) {
            return ""
        }

        if (obj instanceof ArrayList && obj.size() == 0) {
            return ""
        }

        return statement
    }

    static String escapeVal(String value) {
        value = value == null ? "" : value.replaceAll("'", "''")
        return "'$value'"
    }

    static void main(String[] args) {
        String s = """ssss,1123'"""
        println s.replaceAll("'", "''")
        println escapeVal(s)
    }

}
